const puppeteer = require("puppeteer");
const utils     = require('../util/utils');
const config    = require('../config/config');

class jsPlugin{
    constructor(options) {
        console.log(`path:${options.wyfyPluginPath}`)
        if(!jsPlugin.single){
            this.windowOptions = [
                '--disable-web-security',
                `--disable-extensions-except=${options.pluginPath},${options.wyfyPluginPath},${options.googlePluginPath},${options.proxyPath}`,
                `--load-extension=${options.pluginPath},${options.wyfyPluginPath},${options.googlePluginPath},${options.proxyPath}`,
                // `--proxy-server=http://${config.PROXY.HOST}:${config.PROXY.PORT}`,
                `–default-browser-check` //不检查默认浏览器
            ];
            this.browser = null;
            this.page = null;
            this.token = options.token;
            this.timeOptions = { waitUntil: ["domcontentloaded"] };
            this.closeFn = options.closeFn;
            this.username = options.username;
            this.expireTime = options.expireTime;
            this.productId = options.productId;
            this.clientToken = options.clientToken;
            this.bookmarkPath = options.bookmarkPath;
            this.decode = options.decode;
            this.monitorTimers = [];
            jsPlugin.single = this;
        }
        return jsPlugin.single;
    }

    async loadWindow(){
        if(this.browser){
            await this.browser.newPage();
            return;
        }
        this.browser = await puppeteer.launch({
            headless: false,
            ignoreHTTPSErrors: false,
            credentialsEnableService:false,
            ignoreDefaultArgs: ['--enable-automation','--disable-extensions'],
            defaultViewport: {
                width: 0,
                height: 0
            },
            // userDataDir: this.bookmarkPath,
            args: this.windowOptions,

        });
        this.page = await this.browser.newPage();

        this.page.setRequestInterception(true);

        //关闭起始页的page
        await this.closeFirstPage();

        await this.camouflageBrowser();
        await this.intercept();

        await this.goPage('chrome-extension://bckjlihkmgolmgkchbpiponapgjenaoa/login.html');

        let tokenObj = await this.appendTokenInfo(this.token);
        await this.do(JSON.stringify(tokenObj));
        // await this.monitor();

        //打开书签栏
        // await this.openBookMarks();
    }

    async intercept(){
        //开启请求拦截
        this.registerPageRequestEvent(this.page);

        this.page.once('close',async () => {
            await this.closeWindows();
        });
    }

    async registerPageRequestEvent(page){
        page.on('request', async (request) => {
            request.continue();
        });
    }

    async do(tokenObj){
        let tokenDom = await this.page.$("#token");
        if(tokenDom){
            await this.page.evaluate((el, value) => {
                    el.value = value
                },
                tokenDom,
                tokenObj
            );
        }
        await this.page.click('#submit');
    }

    async appendTokenInfo(token){
        let tokenObj = token;
        tokenObj.username = this.username;
        tokenObj.expireTime = this.expireTime;
        tokenObj.productId = this.productId;
        tokenObj.clientToken = this.clientToken;
        return tokenObj;
    }

    async cacheManage(key,value){
        // const client = await this.page.target().createCDPSession();
        // // await client.send('ApplicationCache.enable');
        // let cache = await client.send('Page.getResourceTree');
        // console.log(`Cache:${ window.localStorage.getItem(key)}`)
    }

    async camouflageBrowser(){
        //删掉webdriver属性 以免被检测出为无头浏览器
        await this.page.evaluateOnNewDocument(() => {
            const newProto = navigator.__proto__;
            delete newProto.webdriver;
            navigator.__proto__ = newProto;
        });

        //无头浏览器模式下,全局对象下的chrome对象是没有 runtime属性的
        await this.page.evaluateOnNewDocument(() => {
            window.navigator.chrome = {
                runtime: {}
            };
        });

        this.page.once('close',async () => {
            this.closeFn();
            await this.closeWindows();
        });
    }

    async monitor(){
        //创建element
        // let createInputTimer = setInterval(async () => {
        //     let title = await this.page.title();
        //     if(title.indexOf('Amazon.com') !== -1){
        //         //说明已经跳转到亚马逊网站 设置一个隐藏input用于接收主线程交互的参数
        //         await this.page.evaluate((el, value) => {
        //             let inputElement = document.getElementById('tokenInput');
        //             if(!inputElement){
        //                 console.log(`create element....`)
        //                 inputElement = document.createElement("input");
        //                 inputElement.type = 'text';
        //                 inputElement.id = "tokenInput";
        //                 inputElement.placeholder = 'please input token...';
        //                 inputElement.setAttribute('style','display:none');
        //                 document.getElementById('nav-search').appendChild(inputElement);
        //             }
        //         })
        //     }
        // },500);
        // //刷新cookie
        // let refreshCookieTimer = setInterval(async () => {
        //     let cookie = await this.refreshCookie().catch((e) => {
        //         throw new Error(`刷新cookie失败 error:${e.message}`);
        //     });
        //     await this.setNewCookie(cookie);
        // },1000 * 3);
        //
        // this.monitorTimers.push(createInputTimer);
        // this.monitorTimers.push(refreshCookieTimer);
    }

    async setNewCookie(newCookie){
        await this.page.evaluate((el, value) => {
            let inputElement = document.getElementById('tokenInput');
            console.log(`inputElement:${inputElement}`)
            if(inputElement){
                inputElement.value = value;
            }
        },undefined,JSON.stringify(newCookie))
    }

    /**
     * 关闭浏览器
     * @returns {Promise<void>}
     */
    async closeWindows(){
        this.closeFn && this.closeFn();
        let pages = await this.browser.pages();
        await this.monitorTimers.forEach(item => clearInterval(item));
        await pages.forEach(item => item.close());
        await this.browser.close();
        jsPlugin.single = null;
    }

    /**
     * 刷新cookie
     * @returns {Promise<void>}
     */
    async refreshCookie(){
        return new Promise((resolve, reject) => {
            utils.get('/client-product-users/' + this.productId,'',this.clientToken,async (data) => {
                data = this.decode(JSON.stringify(data));
                data = JSON.parse(data);
                let cookie = data.data.cookie;
                cookie = JSON.parse(cookie);
                resolve(await this.appendTokenInfo(cookie));
            },async (error) => {
                console.log(`刷新Js插件cookie失败 error:${error.message}`);
                reject(error);
            });
        })
/*        return new Promise((resolve, reject) => {

            console.log(`token:${this.clientToken}`)
            request(options,async (err,response,body) => {
                if(err){
                    reject(`刷新cookie失败 error:${err}`)
                }else{
                    body = this.decode(JSON.stringify(body));
                    let data = JSON.parse(body);
                    if(data.code == 200){
                        let cookie = data.data.cookie;
                        let tokenObj = await this.appendTokenInfo(JSON.parse(cookie));
                        resolve(tokenObj);
                    }
                }
            })
        })*/
    }


    /**
     * 访问页面
     * @param url
     * @returns {Promise<void>}
     */
    async goPage(url){
        //打开页面
        await this.page.goto(url,this.timeOptions);
    }

    async closeFirstPage(){
        let pages = await this.browser.pages();
        if(!pages || pages.length === 0){
            return;
        }
        await pages[0].close();
    }

    async openBookMarks() {
        await this.page.keyboard.down('Control');
        // await this.page.keyboard.down('Shift');
        await this.page.keyboard.press('KeyA');
    }
}

jsPlugin.single = null;
// module.exports = jsPlugin;
export default jsPlugin
